﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using CloudClip.Clip;
using CloudClip.HelperMehtod;
using CloudClip.Properties;
using CloudClip.ExtensionMethod;
using ExtensionLibrary.Exception;

namespace CloudClip.LocalFile
{
    public class LocalFileClipProvider : IClipProvider
    {
        public LocalFileClipProvider(Setting setting)
        {
            _setting = setting;

            if (_setting.ClipFolderPath.IsNullOrEmpty() || _setting.ClipFolderPath.CheckDirectoryExist() == false) 
            {
                throw new ValidationException("請先選擇剪貼簿暫存檔案資料夾");
            }

            //監控剪貼簿資源的資料夾是否異動
            FileWatcherHelper.CreateWatcher(_setting.ClipFolderPath, new FileSystemEventHandler(WatcherEvent));
        }

        private void WatcherEvent(object sender, FileSystemEventArgs e)
        {
            IsForderChange = true;
        }

        private bool IsForderChange = true;
        private Setting _setting;
        private List<ClipRow> InfoClipList = new List<ClipRow>();
        private CalFile calFile = new CalFile();
        
        public IClipUnit GetClipData()
        {
            return null;
        }

        public List<ClipRow> GetClipList()
        {
            return InfoClipList;
        }

        public void SyncClipList()
        {
            if (IsForderChange == false)
                return;

            if (string.IsNullOrEmpty(_setting.ClipFolderPath))
                return;

            List<ClipRow> lst = new List<ClipRow>();
            DirectoryInfo directoryInfo = new DirectoryInfo(_setting.ClipFolderPath);

            IOrderedEnumerable<FileInfo> fileInfos = directoryInfo.GetFiles().OrderByDescending(s => s.LastWriteTime);
            foreach (FileInfo fileInfo in fileInfos)
            {
                ClipRow clipRow = InfoClipList.AsParallel().Where(s => s.Name == fileInfo.FullName).FirstOrDefault();

                if (clipRow != null)
                {
                    lst.Add(clipRow);
                }
                else
                {
                    using (StreamReader streamReader = fileInfo.OpenText())
                    {
                        clipRow = new ClipRow();
                        clipRow.Name = fileInfo.FullName;
                        clipRow.ClipUnit = new TextClipUnit(streamReader.ReadToEnd());
                        lst.Add(clipRow);
                    }
                }
            }
            InfoClipList.Clear();
            InfoClipList = lst;

            IsForderChange = false;
        }

        public bool CheckWorking()
        {
            return true;
        }

        public bool SetClipData(IClipUnit clipUnit)
        {
            try
            {
                //先檢查是否已放一樣的剪貼簿內容
                ClipRow CheckClipRow = InfoClipList.AsParallel().Where(s => s.ClipUnit.ToText() == clipUnit.ToText()).FirstOrDefault();
                if (CheckClipRow != null)
                {
                    InfoClipList.Remove(CheckClipRow);
                    FileInfo fileInfo = new FileInfo(CheckClipRow.Name);
                    fileInfo.Delete();
                }

                #region 建立ClipROW

                string sText = clipUnit.ToText();
                string sFileName = Path.Combine(_setting.ClipFolderPath, MD5Helper.CreateMD5Hash(sText).ToFileFormatString());
                using (StreamWriter streamWriter = new StreamWriter(sFileName))
                {
                    streamWriter.Write(sText);
                }

                ClipRow clipRow = new ClipRow();
                clipRow.Name = sFileName;
                clipRow.ClipUnit = clipUnit;

                InfoClipList.Insert(0, clipRow);

                int count = InfoClipList.Count();
                if (count > _setting.ClipSize)
                {
                    for (int i = count; i > _setting.ClipSize; i--)
                    {
                        ClipRow infoClip = InfoClipList[i - 1];
                        InfoClipList.Remove(infoClip);
                    }
                }
                #endregion

                #region 計算是否有超過設定檔個數,這動作也許比較耗時, 丟Thread, 還沒考慮交互的時候

                calFile.InfoClipList = InfoClipList;
                calFile.Setting = _setting;
                Thread thread = new Thread(calFile.CalFileCount);
                thread.Start();

                #endregion
            }
            catch (Exception ex)
            {
                LoggerHelper.WriteDebugLog(ex.ToString() + ex.StackTrace);
            }
            return true;
        }

    }

    public class CalFile
    {
        public Setting Setting;
        public List<ClipRow> InfoClipList;
        public void CalFileCount()
        {
            if (Setting == null)
                return;

            DirectoryInfo directoryInfo = new DirectoryInfo(Setting.ClipFolderPath);
            List<FileInfo> fileInfos = directoryInfo.GetFiles().OrderByDescending(s => s.LastWriteTime).ToList();

            int count = fileInfos.Count() - 1;
            for (int i = count; i >= 0; i--)
            {
                if (i >= Setting.ClipSize)
                {
                    fileInfos[i].Delete();
                }
            }
        }
    }
}
